/*
 * @(#)FormDynamicValueProcessor.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */

package com.dcivision.form.core;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import uk.ltd.getahead.dwr.ExecutionContext;

import com.dcivision.form.FormConstant;
import com.dcivision.form.bean.FormDBlookupSQL;
import com.dcivision.form.bean.FormElement;
import com.dcivision.form.bean.FormElementType;
import com.dcivision.form.bean.FormPage;
import com.dcivision.form.bean.FormRoutingRule;
import com.dcivision.form.bean.FormSelectionField;
import com.dcivision.form.bean.FormSelectionFieldOption;
import com.dcivision.form.bean.MtmFormDynamicValue;
import com.dcivision.form.bean.MtmFormPageFormSection;
import com.dcivision.form.bean.MtmFormSectionFormElement;
import com.dcivision.form.dao.FormDynamicValueDAObject;
import com.dcivision.form.dao.FormElementDAObject;
import com.dcivision.form.dao.FormPageDAObject;
import com.dcivision.form.dao.FormSelectionFieldDAObject;
import com.dcivision.form.dao.FormSelectionFieldOptionDAObject;
import com.dcivision.form.dao.MtmFormDynamicValueDAObject;
import com.dcivision.form.dao.MtmFormPageFormSectionDAObject;
import com.dcivision.form.dao.MtmFormSectionFormElementDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.MessageResourcesFactory;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.workflow.bean.WorkflowStepFormEquat;

/**
FormDynamicValueProcessor.java

This class will call FormDynamicValueDAObject to lookup data from DB.

@author      Charlie liu
@company     DCIVision Limited
@creation date   11/10/2006
@version     $Revision: 1.8.2.1 $
*/

public class FormDynamicValueProcessor {

	public static final String REVISION = "$Revision: 1.8.2.1 $";
	
	private Connection con=null;
	private HttpServletRequest request = null;
	private SessionContainer sessionCon = null;
	private MtmFormDynamicValueDAObject mtmDynamicValueDAO = null;
	private FormDynamicValueDAObject getDynamicValueDAO = null;
	private MtmFormSectionFormElementDAObject mtmSectionElementDAO = null;
	private MtmFormPageFormSectionDAObject mtmPageSectionDAO = null;
	private FormElementDAObject formElementDAObject = null;
	
	private Log log = LogFactory.getLog(this.getClass().getName());
	
	public FormDynamicValueProcessor() {
		super();
	}

	//this method is for form dblookup dynamic_value
	
	public String[]dynamicValueProcess(String id,String value){
		String[] results = null;
		String[] checkBox = null;
		request = ExecutionContext.get().getHttpServletRequest();
		sessionCon = getSessionContainer(request);
		con = getDBConnection();
		mtmDynamicValueDAO = new MtmFormDynamicValueDAObject(sessionCon,con);
		getDynamicValueDAO = new FormDynamicValueDAObject(con);
		MtmFormDynamicValue mtmFormDynamicValue = new MtmFormDynamicValue();
		mtmFormDynamicValue.setConditionElementID(new Integer(id));
		try{
			ArrayList list = (ArrayList)mtmDynamicValueDAO.getListByConditionID(mtmFormDynamicValue);
			int size = list.size();
			log.debug("FORMDBLOOKUP_DYNAMICVALUE_MTM_SIZE = "+size);
			results = new String[list.size()*2];
			mtmSectionElementDAO = new MtmFormSectionFormElementDAObject(sessionCon,con);
			mtmPageSectionDAO = new MtmFormPageFormSectionDAObject(sessionCon,con);
			formElementDAObject = new FormElementDAObject(sessionCon,con);
			
			for(int i = 0 ; i<size ; i++){
				mtmFormDynamicValue = (MtmFormDynamicValue)list.get(i);	
				Integer elementID = mtmFormDynamicValue.getDynamicElementID();
				FormElement formElement = (FormElement)formElementDAObject.getObjectByID(elementID);
				String fieldName = getFieldName(formElement);
				results[2*i] = fieldName;
				log.debug("FORMDBLOOKUP_DYNAMICVALUE_RESULTS["+2*i+"] = " + results[2*i]);
				String sql = mtmFormDynamicValue.getSqlStatement();
				//log.debug("SQLSTATEMENT_before_process = " + sql);
				if(Utility.isEmpty(sql)){
					results[2*i+1]="";
				}else{
		      String[] array = sql.split(FormConstant.FORM_DB_LOOKUP_SQL_SEPARATOR);
		      sql="";		      
		      for(int j= 0 ; j<array.length;j++){
		      	if((array[j]).trim().equals("?")){
		      		if(sql.indexOf("LIKE")>0){
		      			array[j]="'"+value+"'";
		      		}else{
		      			array[j]=value;
		      		}		      		
		      	}
		        sql += array[j]+" ";   
		        //log.debug("array["+j+"] = " + array[j]);     
		      }
		      log.debug("SQLStatement="+sql);
		      String elementType =  formElement.getElementType();
		      boolean moreLine = elementType.equals(FormElementType.ELEMENT_CHECK_BOX);		   
		      Object[] sqlResults = getDynamicValueDAO.getDynamicValue(sql,moreLine);
					if(sqlResults!=null&&sqlResults.length>0){
						if(!moreLine){
							results[2*i+1] = (String)sqlResults[0];
						}else{				  		
				  		FormSelectionFieldDAObject selectionFieldDAObject = new FormSelectionFieldDAObject(sessionCon,con);
				  		FormSelectionFieldOptionDAObject selectionFieldOptionDAObject = new FormSelectionFieldOptionDAObject(sessionCon,con);
				  		FormSelectionField formSelectionField = (FormSelectionField)selectionFieldDAObject.getByElementID(formElement.getID());
				  		List options = selectionFieldOptionDAObject.getListBySelectionFieldID(formSelectionField.getID());
				  		int checkBox_size = options.size();
				  	  checkBox = new String[checkBox_size*2];
				  		results[2*i]="";
				  		for(int k=0;k<checkBox_size;k++){
				  			FormSelectionFieldOption option=(FormSelectionFieldOption)options.get(k);
				  			checkBox[2*k] = fieldName+"_"+option.getID();;
				  			for(int l=0;l<sqlResults.length;l++){
					  			if(option.getStartValue().equals((String)sqlResults[l])){
  				  				checkBox[2*k+1]= "1";				  				
  				  				break;
				  			  }else{
				  				  checkBox[2*k+1]= "0";				  				
				  			  }				  				
				  			}
				  			log.debug("checkBox["+(2*k)+"] = " + checkBox[2*k]);
				  			log.debug("checkBox["+(2*k+1)+"] = " + checkBox[2*k+1]);
				  		}
				  	}
					}else{
						results[2*i+1] = "";
					}
				}
				log.debug("FORMDBLOOKUP_DYNAMICVALUE_RESULTS["+(2*i+1)+"] = " + results[2*i+1]);
			}
			//add results and checkBox both array to a new array 
			if(checkBox!=null&&checkBox.length>0){
				String[] newResults = new String[results.length+checkBox.length];
				for(int i=0;i<newResults.length;i++){
					if(i<results.length){
						newResults[i]=results[i];
					}else{
						newResults[i]=checkBox[i-results.length];
					}
					log.debug("newResults["+i+"]= "+newResults[i]);
				}
				results = newResults;
			}
		}catch(Exception e){
			log.error("Form DBLook UP Dynamic value Error! "+ e);
		}finally {
			try {
				if (con != null)
 					 con.close();
			} catch (SQLException e) {
        log.error(e, e);
				throw new RuntimeException("error.unexpecte");
			}
		}
		return results;
	}
	
	//this method is for default value of form elements(Selection Box/Radio Box/Check Box).
	
	public List getSelectionValues(String field, String table, String condition) {
		FormDBlookupSQL sql = new FormDBlookupSQL(field, table, condition);		
		if (sql.validator().equals("error"))
			return null;		
		List values = new ArrayList();
		con = getDBConnection();
		try{			
			getDynamicValueDAO = new FormDynamicValueDAObject(con);
		  values = getDynamicValueDAO.getList(sql);
		}catch(Exception e){
			log.error("Form DBLook UP Dynamic value Error! "+ e);
		}finally {
			try {
				if (con != null)
 					 con.close();
			} catch (SQLException e) {
        log.error(e, e);
				throw new RuntimeException("error.unexpecte");
			}
		}		
		return values;
	}
	
	//get SessionContainer Object.
	
  private SessionContainer getSessionContainer(HttpServletRequest request) {
    SessionContainer ctx = (SessionContainer)request.getSession().getAttribute(GlobalConstant.SESSION_CONTAINER_KEY);
    if (ctx==null) {
      ctx = new SessionContainer();
      request.getSession().setAttribute(GlobalConstant.SESSION_CONTAINER_KEY, ctx);
    }
    return(ctx);
  }
  
  //get Connection Object.
  
  private Connection getDBConnection(){
  	if(this.con!=null){
  		return con;
  	}else{
  		try{
  			con=DataSourceFactory.getConnection();
  		}catch(Exception e){
  			log.error("get Connection error!");
  		}
  		return con;
  	}
  }
  
  //get element fieldName
  
  private String getFieldName(FormElement element)throws ApplicationException{
  	
  	String fieldName="";  	
  	MtmFormSectionFormElement mtmSectionElement = new MtmFormSectionFormElement();
  	mtmSectionElement = (MtmFormSectionFormElement)mtmSectionElementDAO.getObjectByElementID(element.getID());  	
  	
  	MtmFormPageFormSection mtmPageSection = new MtmFormPageFormSection();
  	mtmPageSection = (MtmFormPageFormSection)mtmPageSectionDAO.getObjectBySectionID(mtmSectionElement.getSectionID());  	  	
  	
  	// element.setRowIndex(mtmSectionElement.getRowIndex());  	
  	
  	Integer pageID = mtmPageSection.getPageID();
  	//log.debug("pageID="+pageID);
  	Integer sectionID = mtmSectionElement.getSectionID();
  	//log.debug("sectionID="+sectionID);
  	// String sectionSeq = "1";
  	//log.debug("sectionSeq="+sectionSeq);
  	// String elementSeq = "1";
  	//log.debug("elementSeq="+elementSeq);
  	//log.debug("RowIndex="+mtmSectionElement.getRowIndex());
  	
  	FormSubmissionManager formSubmissionManager = new FormSubmissionManager(sessionCon,con);
  	fieldName = formSubmissionManager.getFieldName(element,pageID,sectionID);
  	return fieldName;
  }
  
  public String getOperationTypeMap(String Ruletype,String haveDate,String haveNumber){
    String result = new String();
    request = ExecutionContext.get().getHttpServletRequest();
    sessionCon = this.getSessionContainer(request);
    if (Ruletype.equals(FormRoutingRule.ROUTING_TYPE_CALCULATE)){
      result = "{"+WorkflowStepFormEquat.OPERATION_TYPE_NUMBER+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.operation_type_number")+"'}";
      
    }else{
      result = "{"+WorkflowStepFormEquat.OPERATION_TYPE_STRING+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.operation_type_string")+"'";
      if (haveNumber.equals("true")){
        result += ","+WorkflowStepFormEquat.OPERATION_TYPE_NUMBER+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.operation_type_number")+"'";
      }
      if (haveDate.equals("true")){
        result += ","+WorkflowStepFormEquat.OPERATION_TYPE_DATE+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.operation_type_date")+"'";
      }
      result += "}";
//      result = "{"+WorkflowStepFormEquat.OPERATION_TYPE_STRING+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.operation_type_string")+"'" +
//          ","+WorkflowStepFormEquat.OPERATION_TYPE_NUMBER+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.operation_type_number")+"'" +
//          ","+WorkflowStepFormEquat.OPERATION_TYPE_DATE+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.operation_type_date")+"'}";

      
    }   
    return result;
  }
  
  public String getElmentList(String Ruletype,String operationType,String formRecordID)throws ApplicationException{
    request = ExecutionContext.get().getHttpServletRequest();
    sessionCon = this.getSessionContainer(request);
    con = this.getDBConnection();
    FormPageDAObject formPageDAO = new FormPageDAObject(sessionCon,con);
    FormElementDAObject formElementDAO = new FormElementDAObject(sessionCon,con);
    MtmFormPageFormSectionDAObject pageSectionDAO = new MtmFormPageFormSectionDAObject(sessionCon,con);
    MtmFormSectionFormElementDAObject sectionElementDAO = new MtmFormSectionFormElementDAObject(sessionCon,con);
    List formElementList = new ArrayList();
    try{
      if(!Utility.isEmpty(formRecordID)){
        List formPageList = formPageDAO.getDetailListByFormRecordID(new Integer(formRecordID));
        for(int j=0; j<formPageList.size(); j++){
          FormPage formPage = (FormPage)formPageList.get(j);
          List pageSectionList = pageSectionDAO.getListByPageID(formPage.getID());
          for (int k=0; k<pageSectionList.size(); k++){
            MtmFormPageFormSection pageSection = (MtmFormPageFormSection)pageSectionList.get(k);
            List sectionElementList = sectionElementDAO.getListBySectionID(pageSection.getSectionID());
            for(int n=0; n<sectionElementList.size(); n++){
              MtmFormSectionFormElement sectionElement = (MtmFormSectionFormElement)sectionElementList.get(n);
              FormElement formElement = (FormElement)formElementDAO.getObjectByID(sectionElement.getElementID());
              if(!Utility.isEmpty(Ruletype) && FormRoutingRule.ROUTING_TYPE_CALCULATE.equals(Ruletype)){
                if(FormElementType.ELEMENT_TEXT.equals(formElement.getElementType()) 
                        && (FormElement.VALIDATION_INTEGER_ONLY.equals(formElement.getValidationRule()) || 
                            FormElement.VALIDATION_NUMERIC_ONLY.equals(formElement.getValidationRule()) )){
                  formElement.setFormRecordID(formRecordID.toString());
                  formElement.setFormPageID(formPage.getID().toString());
                  formElement.setFormSectionID(pageSection.getSectionID().toString());
                  formElementList.add(formElement);  
                }
              }else {
                if(!Utility.isEmpty(Ruletype) && WorkflowStepFormEquat.OPERATION_TYPE_NUMBER.equals(operationType)){
                  if(FormElementType.ELEMENT_TEXT.equals(formElement.getElementType()) 
                      && (FormElement.VALIDATION_INTEGER_ONLY.equals(formElement.getValidationRule()) || 
                          FormElement.VALIDATION_NUMERIC_ONLY.equals(formElement.getValidationRule()) )){
                    formElement.setFormRecordID(formRecordID.toString());
                    formElement.setFormPageID(formPage.getID().toString());
                    formElement.setFormSectionID(pageSection.getSectionID().toString());
                    formElementList.add(formElement);  
                    
                  }
                }else if(!Utility.isEmpty(Ruletype) && WorkflowStepFormEquat.OPERATION_TYPE_DATE.equals(operationType)){  
                  if(FormElementType.ELEMENT_DATE_PICKER.equals(formElement.getElementType()) ||
                           FormElementType.ELEMENT_CURRENT_DATE.equals(formElement.getElementType()) ){ 
                    formElement.setFormRecordID(formRecordID.toString());
                    formElement.setFormPageID(formPage.getID().toString());
                    formElement.setFormSectionID(pageSection.getSectionID().toString());
                    formElementList.add(formElement);
                  }
                }else{
                  if(FormElementType.ELEMENT_TEXT.equals(formElement.getElementType()) ||
                      FormElementType.ELEMENT_TEXT_AREA.equals(formElement.getElementType()) ||
                      FormElementType.ELEMENT_DATE_PICKER.equals(formElement.getElementType()) ||
                      FormElementType.ELEMENT_CHECK_BOX.equals(formElement.getElementType()) || 
                      FormElementType.ELEMENT_SELECTION_BOX.equals(formElement.getElementType()) ||
                      FormElementType.ELEMENT_RADIO_BUTTON.equals(formElement.getElementType()) ){
                    
                    formElement.setFormRecordID(formRecordID.toString());
                    formElement.setFormPageID(formPage.getID().toString());
                    formElement.setFormSectionID(pageSection.getSectionID().toString());
                    formElementList.add(formElement);
                                    
                  }  
                }
              }
            }
          }
        }
      }
    } catch (ApplicationException appEx) {
      throw appEx;
    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    } finally {
    }
    String formElementStr ="";

    formElementStr= formElementList.size()>0 ? "{" : "";
    for (int i=0; i<formElementList.size(); i++){
      FormElement formElement = (FormElement)formElementList.get(i);
      String elementName = WorkflowStepFormEquat.ELEMENT_PREFIX_CHAR + formElement.getFormPageID()+"_"+formElement.getFormSectionID()+"_"+formElement.getID();
      formElementStr += formElementStr.length()>1 ? ","+elementName+":'"+formElement.getFieldName()+"'" : elementName+":'"+formElement.getFieldName()+"'";      
    } 
    formElementStr += formElementStr.length()>0 ? "}" : "";
    return formElementStr;
  }

  public String getOperand(String Ruletype,String operationType)throws ApplicationException{
    String result = "";
    request = ExecutionContext.get().getHttpServletRequest();
    sessionCon = this.getSessionContainer(request);
    if (WorkflowStepFormEquat.OPERATION_TYPE_NUMBER.equals(operationType)){
      result = "{'+':'+','-':'-','*':'*','/':'/'";
      if (!FormRoutingRule.ROUTING_TYPE_CALCULATE.equals(Ruletype)){
        result += ",'>':'>','>=':'>=','=':'=','<>':'<>','<':'<','<=':'<='}";
      }else{
        result += "}";
      }
    } else if(WorkflowStepFormEquat.OPERATION_TYPE_STRING.equals(operationType)){
      result = "{"+WorkflowStepFormEquat.STRING_OPERATION_EQUALS+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.date_operation_equals")+"'" +
               ","+WorkflowStepFormEquat.STRING_OPERATION_NOT_EQUALS+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"form.label.string_operation_not_equals")+"'" +
               ","+WorkflowStepFormEquat.STRING_OPERATION_IS_EMPTY+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"form.label.string_operation_is_empty")+"'" +
               ","+WorkflowStepFormEquat.STRING_OPERATION_IS_NOT_EMPTY+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"form.label.string_operation_is_not_empty")+"'" +
               ","+WorkflowStepFormEquat.STRING_OPERATION_CONTAINS+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"common.options.criteria.contains")+"'" +
               ","+WorkflowStepFormEquat.STRING_OPERATION_STARTS_WITH+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"common.options.criteria.starts_with")+"'}";
    } else if(WorkflowStepFormEquat.OPERATION_TYPE_DATE.equals(operationType)){
      result = "{"+WorkflowStepFormEquat.DATE_OPERATION_BEFORE+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.date_operation_before")+"'" +
               ","+WorkflowStepFormEquat.DATE_OPERATION_EQUALS+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.date_operation_equals")+"'" +
               ","+WorkflowStepFormEquat.DATE_OPERATION_AFTER+":'"+MessageResourcesFactory.getMessage(this.sessionCon.getSessionLocale(),"workflow.label.date_operation_after")+"'}";
    }    
    return result;
  }
  
  public String getRuleList(String formEquationItem,String formEquationListValue){
    request = ExecutionContext.get().getHttpServletRequest();
    String formEquationArr[] = null;
    if(!Utility.isEmpty(formEquationListValue)){
      formEquationArr = TextUtility.splitString(formEquationListValue,"$$");
    }   
    String[] deleteItemArr = request.getParameterValues("deleteItem");

    formEquationListValue = "";   
    for(int j=0; !Utility.isEmpty(formEquationArr) &&  j<formEquationArr.length; j++){     
      if (!"formEquationArr[j]".startsWith("&&") && !Utility.isEmpty(formEquationArr[j])){
        formEquationListValue += "$$" + formEquationArr[j];
      }else{
        formEquationListValue += formEquationArr[j];
      }
    }
    if(Utility.isEmpty(formEquationListValue) && !Utility.isEmpty(formEquationItem) ){
      formEquationListValue = "$$" + formEquationItem;
    } else if(!Utility.isEmpty(formEquationItem)) {
      formEquationListValue += "$$" + formEquationItem;  
    }
    return formEquationListValue;  
  }
  
  public String getOperator(String elementStr) throws ApplicationException {
  	request = ExecutionContext.get().getHttpServletRequest();
    sessionCon = this.getSessionContainer(request);
    con = this.getDBConnection();
    FormElementDAObject formElementDAO = new FormElementDAObject(sessionCon,con);
    String operatorComment = "";
    StringBuffer tmpComment = new StringBuffer();
    String elementID = elementStr.substring(0,elementStr.lastIndexOf("_"));
    elementID = elementID.substring(elementID.lastIndexOf("_")+1,elementID.length());
    
    
    FormElement formElement = (FormElement)formElementDAO.getObjectByID(new Integer(elementID)); 
    
    List formSelectionFieldOptionList = new ArrayList();
    FormSelectionField formSelectionField = formElement.getFormSelectionField();
    if (!Utility.isEmpty(formSelectionField)){
    	formSelectionFieldOptionList = formSelectionField.getFormSelectionFieldOptionList();
    }
    
    for (int k=0; k<formSelectionFieldOptionList.size(); k++) {
    	FormSelectionFieldOption tmpFormSelectionFieldOption = (FormSelectionFieldOption) formSelectionFieldOptionList.get(k);
    	if (k==0){
    		tmpComment.append("<select name='value'>");   
    	}
    	tmpComment.append("<option value='" + tmpFormSelectionFieldOption.getStartValue() + "'>");
    	tmpComment.append(" " + tmpFormSelectionFieldOption.getLabel() + " ");
    	tmpComment.append("</option>");
    }
    operatorComment = tmpComment.toString();
    return operatorComment;
  }
  

}
